package com.teatime.client.image.photomgr;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.teatime.client.Constants;
import com.teatime.client.R;
import com.teatime.client.TLog;
import com.teatime.client.TeaTimeUtils;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class PhotoMgrView extends LinearLayout
					implements OnClickListener, 
						DialogInterface.OnClickListener {

	private View mChildView;
	private PhotoStackView mPhotoList;
	private ImageView mImgPhotoAdd;
	private PhotoMgrPopWin mPopWin;
	private List<PhotoInfo> mPhotos;
	
	public PhotoMgrView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		mChildView = null;
		mPhotos = new ArrayList<PhotoInfo>();
		
		initAttr(attrs);
		if (mChildView == null) {
			LayoutInflater factory = LayoutInflater.from(getContext());
			mChildView = factory.inflate(R.layout.view_photo_mgr, null);
        }
	}
	
	protected void initAttr(AttributeSet attrs) {
		
		TypedArray a = getContext().obtainStyledAttributes(attrs,
                R.styleable.teatime);
		if (a == null) {
			return;
		}
		
		for (int i = 0; i < a.getIndexCount(); i ++) {
            int attr = a.getIndex(i);
            switch (attr) {
            case R.styleable.teatime_childLayout:
            	int vid = a.getResourceId(attr, -1);
            	if (vid > 0) {
            		LayoutInflater factory = LayoutInflater.from(getContext());
            		mChildView = factory.inflate(vid, null);
                   
            	}
            	break;
            }
        }
        a.recycle();
        
	}
	
	public void onFinishInflate() {
		if (mChildView != null) {
			addView(mChildView);
			mImgPhotoAdd = (ImageView)mChildView.findViewById(R.id.img_photo_add);
			if (mImgPhotoAdd != null) {
				mImgPhotoAdd.setOnClickListener(this);
			}
			
			mPhotoList = (PhotoStackView)mChildView.findViewById(R.id.photo_list_stack);
			if (mPhotoList != null) {
				mPhotoList.setOnClickListener(this);
			}
			
		}
		
	}
	
	public PhotoInfo findByBitmap(Bitmap bitmap) {
		for (int i = 0; i < mPhotos.size(); i ++) {
			PhotoInfo pi = mPhotos.get(i);
			if (bitmap == pi.bitmap) {
				return pi;
			}
		}
		return null;
	}
	
	public void delBitmap(Bitmap bitmap) {
		PhotoInfo pi = findByBitmap(bitmap);
		if (!bitmap.isRecycled()) {
			bitmap.recycle();
		}
		if (pi != null) {
			mPhotos.remove(pi);
		}
	}
	
	private Bitmap createSmallBitamp(Bitmap src) {
		int dstWidth  = TeaTimeUtils.dip2px(getContext(), 
				Constants.SmallImageWidth),
			dstHeight = TeaTimeUtils.dip2px(getContext(),
					Constants.SmallImageHeight),
			srcWidth  = src.getWidth(),
			srcHeight = src.getHeight();
		if (srcWidth > dstWidth 
			|| srcHeight > dstHeight) {
			float scale = Math.max((float)dstWidth / (float)srcWidth, 
					(float)dstHeight / (float)srcHeight);
			if (scale > 3.0f) {
				scale = 3.0f;
			}
			Matrix matrix = new Matrix();
			matrix.setScale(scale, scale);
			return Bitmap.createBitmap(src, 0, 0, srcWidth, srcHeight, matrix, false);
		}
		else {
			return Bitmap.createBitmap(src);
		}
	}
	
	protected void addBitmap(Uri imageUri) {
		Bitmap bitmap = null;
		ContentResolver resolver = getContext().getContentResolver();
		//photo = BitmapFactory.decodeFile(uri.getPath());
		try {
			bitmap = MediaStore.Images.Media.getBitmap(resolver, imageUri);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (bitmap == null) {
			TLog.e("PhotoMgrView.addBitmap, "
					+ "load bitmap by uri failed, uri:" 
					+ imageUri.toString());
			return;
		}
		// to save memory, 
		// we use the small size image
		Bitmap smallBmp = createSmallBitamp(bitmap);
		PhotoInfo pi = new PhotoInfo();
		pi.bitmap = smallBmp;
		pi.uri = imageUri;
		mPhotos.add(pi);
		if (mPhotoList != null) {
			mPhotoList.addBitmap(smallBmp);
		}
	}

	@Override
	public void onClick(View view) {
		// TODO Auto-generated method stub
		if (mImgPhotoAdd == view
			|| (mPhotoList == view && mPhotos.size() <= 0)) {
			new AlertDialog.Builder(getContext())
			.setTitle(R.string.title_select_photo_src)
			.setItems(R.array.item_dlg_select_photo_src, 
					this)
			.show();
		}
		else if (mPhotoList == view) {
			popWinPopup();
	        TLog.v("click photolist");
		}
	}

	@Override
	public void onClick(DialogInterface dialog, int which) {
		dialog.dismiss();
		switch(which) {
		case 0:
			onFromGallery();
			break;
		case 1:
			onTakePhoto();
			break;
		}
		
	}
	
	private void onTakePhoto() {
		Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        //i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
		((Activity)getContext()).startActivityForResult(i, Constants.INTENT_CODE_TAKE_PHOTO);
	}
	
	private void onFromGallery() {
		Intent i = getGalleryPickIntent();
		((Activity)getContext()).startActivityForResult(i, Constants.INTENT_CODE_FROM_GALLERY);  
	}
	
	private Intent getGalleryPickIntent() {  
        Intent intent = new Intent(Intent.ACTION_PICK, null);  
        intent.setType("image/*");
        //intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 80);
        intent.putExtra("outputY", 80);
        intent.putExtra("return-data", true);
        return intent;  
    }
	
	public boolean onActivityResult(int requestCode, int resultCode,
	            Intent intent) {
		
		switch(requestCode) {
		case Constants.INTENT_CODE_TAKE_PHOTO:
			onTakePhotoResult(resultCode, intent);
			return true;
		case Constants.INTENT_CODE_FROM_GALLERY:
			onFromGalleryResult(resultCode, intent);
			return true;
		}
		return false;
    }
	
	public void onTakePhotoResult(int resultCode, Intent intent) {
		if (resultCode != Activity.RESULT_OK) {
			return;
		}
		//Bitmap photo = null;
		/*Uri uri = intent.getData();
		if (uri != null) {
			photo = BitmapFactory.decodeFile(uri.getPath());
			if (photo != null) {
				TLog.v("from uri=" + uri.toString());
			}
			else {
				TLog.v("from uri failed, " + uri.toString());
			}
		}
		if (photo == null) {
			Bundle bundle = intent.getExtras();
			if (bundle != null) {
				photo = (Bitmap) bundle.get("data");
				TLog.v("from bundle");
			}
		}
		if (photo == null) {
			TLog.e("get image from camera failed!");
			return;
		}*/
		
		Uri uri = intent.getData();
		if (uri == null) {
			TLog.e("get image from camera failed!");
			return;
		}
		
		TLog.v("get image from camera: " + uri.toString());
		addBitmap(uri);
	}
	
	public void onFromGalleryResult(int resultCode, Intent intent) {
		if (resultCode != Activity.RESULT_OK) {
			return;
		}
		
		/*
		Bitmap photo = intent.getParcelableExtra("data");
		if (photo != null) {
			TLog.v("getParcelableExtra");
		}
		if (photo == null) {
			Uri uri = intent.getData();
			if (uri != null) {
				ContentResolver resolver = getContext().getContentResolver();
				//photo = BitmapFactory.decodeFile(uri.getPath());
				try {
					photo = MediaStore.Images.Media.getBitmap(resolver, uri);
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				if (photo != null) {
					TLog.v("from uri=" + uri.toString());
				}
				else {
					TLog.v("from uri failed, " + uri.toString());
				}
			}
		}
		
		if (photo == null) {
			Bundle bundle = intent.getExtras();
			if (bundle != null) {
				photo = (Bitmap) bundle.get("data");
				if (photo != null) {
					TLog.v("from bundle");
				}
			}
		}
		
		if (photo == null) {
			TLog.e("get image from gallery failed!");
			return;
		}
		*/
		Uri uri = intent.getData();
		if (uri == null) {
			TLog.e("get image from gallery failed!");
			return;
		}
		
		TLog.v("get image from gallery: " + uri.toString());
       	addBitmap(uri);
        
     }
	
	public void popWinPopup() {
		if (mPopWin == null) {
			mPopWin = new PhotoMgrPopWin(getContext(), this);
		}
		//mPopWin.open(this, mPhotos);
		//mPopWin.open(((Activity)getContext()).getWindow().getDecorView(), mPhotos);
		mPopWin.open(mPhotos);
	}

	private void updatePhotos(List<Bitmap> updated) {
		List<PhotoInfo> newPhotos = new ArrayList<PhotoInfo>();
		for (int i = 0; i < updated.size(); i ++) {
			Bitmap bmp = updated.get(i);
			if (bmp != null) {
				PhotoInfo pi = findByBitmap(bmp);
				if (pi != null) {
					newPhotos.add(pi);
				}
			}
		}
		mPhotos.clear();
		mPhotos = newPhotos;
		mPhotoList.updatePhotos(mPhotos);
	}
	
	public void onPhotoMgrPopWinClosed(boolean del, boolean sort, List<Bitmap> updated) {
		// TODO Auto-generated method stub
		if (del || sort) {
			updatePhotos(updated);
		}
	}
	
	public class PhotoInfo {
		public Bitmap bitmap;
		public Uri uri;
	}
	
}
